import { prisma } from './mysql.js';
import n2data from './n2data.js';
import { logger } from '../tools/index.js';

export const createIncome = async ({ primaryTag, minorTags, amount, remark }, context) => {
    return await createTransaction({ primaryTag, minorTags, amount, remark }, TradeType.INCOME, TranscationType.INCOME, context);
}

export const createExpense = async ({ primaryTag, minorTags, amount, remark }, context) => {
    return await createTransaction({ primaryTag, minorTags, amount, remark }, TradeType.EXPENSE, TranscationType.EXPENSE, context);
}

export const createBudget = async ({ primaryTag, minorTags, amount, remark }, context) => {
    return await createTransaction({ primaryTag, minorTags, amount, remark }, TradeType.BUDGET, null, context);
}

export const createTransfer = async ({ primaryTag, minorTags, amount, remark, transferAccount }, context) => {
    const tagsArray = [];
    if (primaryTag) {
        tagsArray.push(primaryTag);
    }
    if (minorTags) {
        minorTags.split(",").forEach(tag => tagsArray.push(tag));
    }
    const tags = tagsArray.join(',');

    const fromAccount = {
        id: context.user.id,
        name: context.user.name
    };

    const matchAtWxUser = context.user.atWxUsers.find(wxUser => wxUser.name === transferAccount);
    if (!matchAtWxUser) {
        throw new Error(`未找到转入账户信息，转入账户名称：${transferAccount}`);
    }
    const toAccount = {
        id: matchAtWxUser.id,
        name: matchAtWxUser.name
    };

    const transactionId = await prisma.$transaction(async prisma => {

        // 变更交易记录
        const transactionRecord = await prisma.t_transaction.create({
            data: {
                book_id: context.book.id,
                book_name: context.book.name,
                trade_type: TradeType.TRANSFER,
                from_account_no: fromAccount.id,
                from_account_name: fromAccount.name,
                from_amount: amount,
                to_account_no: toAccount.id,
                to_account_name: toAccount.name,
                to_amount: amount,
                trade_amount: amount,
                remark: remark,
                tags: tags,
                create_account_no: context.user.id,
                create_account_name: context.user.name,
                terminal: context.terminal,
                request_id: context.request_id
            },
            select: {
                id: true,
            }
        });

        // 同步变更标签
        for (const tag of tagsArray) {
            await prisma.t_transaction_tags.create({
                data: {
                    gmt_create: new Date(),
                    book_id: context.book.id,
                    transaction_id: transactionRecord.id,
                    tag: tag
                }
            });
        }

        // 同步变更流水
        await prisma.t_trans_end_balance.create({
            data: {
                transaction_id: transactionRecord.id,
                account_no: fromAccount.id,
                account_name: fromAccount.name,
                book_id: context.book.id,
                book_name: context.book.name,
                trans_type: TranscationType.EXPENSE,
                trans_amount: amount,
                status: '正常',
            }
        });
        await prisma.t_trans_end_balance.create({
            data: {
                transaction_id: transactionRecord.id,
                account_no: toAccount.id,
                account_name: toAccount.name,
                book_id: context.book.id,
                book_name: context.book.name,
                trans_type: TranscationType.INCOME,
                trans_amount: amount,
                status: '正常',
            }
        });
        return transactionRecord.id;
    });

    return transactionId;
}

export const createTransaction = async ({ primaryTag, minorTags, amount, remark }, tradeType, transcationType, context) => {
    const tagsArray = [];
    if (primaryTag) {
        tagsArray.push(primaryTag);
    }
    if (minorTags) {
        minorTags.split(",").forEach(tag => tagsArray.push(tag));
    }
    const tags = tagsArray.join(',');

    const transactionId = await prisma.$transaction(async prisma => {

        // 变更交易记录
        const transactionRecord = await prisma.t_transaction.create({
            data: {
                book_id: context.book.id,
                book_name: context.book.name,
                trade_type: tradeType,
                from_account_no: null,
                from_account_name: null,
                from_amount: null,
                to_account_no: null,
                to_account_name: null,
                to_amount: null,
                trade_amount: amount,
                remark: remark,
                tags: tags,
                create_account_no: context.user.id,
                create_account_name: context.user.name,
                terminal: context.terminal,
                request_id: context.request_id
            },
            select: {
                id: true,
            }
        });

        // 同步变更标签
        for (const tag of tagsArray) {
            await prisma.t_transaction_tags.create({
                data: {
                    gmt_create: new Date(),
                    book_id: context.book.id,
                    transaction_id: transactionRecord.id,
                    tag: tag
                }
            });
        }

        // 同步变更流水
        if (transcationType) {
            await prisma.t_trans_end_balance.create({
                data: {
                    transaction_id: transactionRecord.id,
                    account_no: context.user.id,
                    account_name: context.user.name,
                    book_id: context.book.id,
                    book_name: context.book.name,
                    trans_type: transcationType,
                    trans_amount: amount,
                    status: '正常',
                }
            });
        }
       
        return transactionRecord.id;
    });

    return transactionId;
}

export const queryTransactionById = async (transactionId, bookId) => {
    return prisma.t_transaction.findUnique({ where: { book_id: bookId, id: transactionId } });
}

export const deleteTransaction = async (transactionId, bookId, operateUserId) => {
    await checkPermission(transactionId, operateUserId);
    await prisma.$transaction(async prisma => {
        // 删除交易信息
        await prisma.t_transaction.delete({
            where: {
                book_id: bookId,
                id: transactionId
            }
        });

        // 同步删除流水
        await prisma.t_trans_end_balance.deleteMany({
            where: {
                book_id: bookId,
                transaction_id: transactionId
            }
        });

        // 同步删除标签映射
        await prisma.t_transaction_tags.deleteMany({
            where: {
                book_id: bookId,
                transaction_id: transactionId
            }
        });
    });
}

// 修改账务标签信息
export const updateFundTags = async (transactionId, bookId, operateUserId, updateTags) => {
    await checkPermission(transactionId, operateUserId);
    await prisma.$transaction(async prisma => {
        // 修改交易标签
        await prisma.t_transaction.update({
            where: {
                book_id: bookId,
                id: transactionId
            },
            data: {
                tags: updateTags.join(',')
            }
        });

        // 同步修改标签映射表
        await prisma.t_transaction_tags.deleteMany({
            where: {
                book_id: bookId,
                transaction_id: transactionId
            }
        });
        for (const tag of updateTags) {
            await prisma.t_transaction_tags.create({
                data: {
                    gmt_create: new Date(),
                    book_id: bookId,
                    transaction_id: transactionId,
                    tag: tag
                }
            });
        }
    });
}

/**
* 自然语言查询交易信息
*/
export const n2DataByTransaction = async (question, context, maxSize) => {
   const tableSchema = {
       table_id: 't_transaction',
       table_desc: '支出/收入/转账等明细记录表',
       columns: [
           { col_name: 'id', col_caption: '明细ID' },
           { col_name: 'book_name', col_caption: '归属账本名称' },
           { col_name: 'trade_type', col_caption: `交易类型，可选[${Object.values(TradeType).join('、')}]`, useFilter: true },
           { col_name: 'tags', col_caption: '逗号分隔的分类标签，示例：餐饮,交通...', useFilter: true },
           { col_name: 'trade_amount', col_caption: '交易金额，保留两位小数', useFilter: true },
           { col_name: 'remark', col_caption: '交易备注的明细信息', useFilter: true },
           { col_name: 'create_time', col_caption: '录入时间，格式：yyyy-mm-dd HH:mm:ss', useFilter: true },

           { col_name: 'create_account_name', col_caption: '创建人账号' },
           { col_name: 'from_account_name', col_caption: '转账人账号' },
           { col_name: 'to_account_name', col_caption: '转账对象账号' },
       ]
   }
   const [tableData, sql] = await n2data(question, tableSchema, context, maxSize, [
       {
           input: `获取近一周的支出明细`,
           output: `SELECT * FROM t_transaction WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND trade_type = '支出'`
       },
       {
           input: `获取所有的餐饮类型支出`,
           output: `SELECT * FROM t_transaction WHERE tags LIKE '%餐饮%' AND trade_type = '支出'`
       }
   ]);

   return tableData;
}

/**
 * 同步所有交易的标签信息
 */
export const syncTransactionTags = async () => {
    const rows = await prisma.t_transaction.findMany();
    for(let i = 0; i < rows.length; i++) {
        const row = rows[i];
        logger.info(`syncTransactionTags process ${row.id}, progress: [${i + 1}/${rows.length}]`);
        const dbTags = (row.tags || '').split(',');
        
        await prisma.$transaction(async prisma => {
            await prisma.t_transaction_tags.deleteMany({
                where: {
                    transaction_id: row.id,
                }
            });
            
            for (const tag of dbTags) {
                await prisma.t_transaction_tags.create({
                    data: {
                        gmt_create: row.create_time,
                        book_id: row.book_id,
                        transaction_id: row.id,
                        tag: tag
                    }
                });
            }
        });
    }
}

/**
 * 校验交易单的操作权限
 */
const checkPermission = async (transactionId, operateUserId) => {
    const transaction = await prisma.t_transaction.findUnique({
        where: {
            id: transactionId,
        }
    });
    if (!transaction) {
        throw new Error(`未找到ID为 ${transactionId} 的交易记录`);
    }
    if (operateUserId !== transaction.create_account_no) {
        throw new Error(`无权变更ID为 ${transactionId} 的交易记录，该记录由 ${transaction.create_account_name} 创建`);
    }
}

export const TradeType = {
    INCOME: '收入',
    EXPENSE: '支出',
    TRANSFER: '转账',
    BUDGET: '预算'
}

export const TranscationType = {
    INCOME: '收入',
    EXPENSE: '支出',
}